/*
 * @Author: your name
 * @Date: 2021-09-01 10:54:22
 * @LastEditTime: 2021-09-26 16:36:23
 * @LastEditors: zhl
 * @Description: In User Settings Edit
 * @FilePath: \Test\src\Parse_Packet.cpp
 */
#include "Parse_Packet.h"
#include <iostream>
#include <string.h>


Parse_Packet  Parse_Packet::c_instance;


Parse_Packet::Parse_Packet(){

}

Parse_Packet::~Parse_Packet(){

}
//
Parse_Packet &Parse_Packet::getInstance(){
    return c_instance;
}
DLT698_FRAME *Parse_Packet::get_frame(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){

    }
    return NULL;
}

uint8_t  Parse_Packet::get_frame_sc(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        return pFrame[0];
    }
    return 0;
}

uint16_t Parse_Packet::get_frame_l(const uint8_t *frame, int len){
    //需要判断大小端
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        return *(uint16_t *)(pFrame+1);
    }
    return 0;
}

uint8_t  Parse_Packet::get_frame_c(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        return pFrame[3];
    }
    return 0;
}

uint8_t  Parse_Packet::get_frame_sa_sc(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        return pFrame[4];
    }
    return 0;
}

pair<uint8_t, uint8_t*>  Parse_Packet::get_frame_sa(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        int len = get_frame_sa_sc_addr_len(pFrame[4]);
        int offset = len+5;
        return make_pair(len, pFrame+offset);
    }
    return make_pair((uint8_t)0, (uint8_t *)NULL);
}

uint8_t  Parse_Packet::get_frame_ca(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        int idx = 5+get_frame_sa_sc_addr_len(frame[4]);
        return pFrame[idx];
    }
    return 0;
}

uint16_t Parse_Packet::get_frame_hcs(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        int offset = 5+get_frame_sa_sc_addr_len(pFrame[4])+1;
        return *(uint16_t *)(pFrame+offset);
    }
    return 0;
}

pair<uint16_t, uint8_t*> Parse_Packet::get_apdu(const uint8_t *frame, int len){

    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        uint16_t len = *(uint16_t *)(pFrame+1);
        int offset = 5+get_frame_sa_sc_addr_len(pFrame[4])+1+2;
        len -= offset;
        len -= 1;
        return make_pair(len, pFrame+offset);
    }
    return make_pair((uint16_t)0, (uint8_t *)NULL);
}

uint16_t Parse_Packet::get_apdu_len(const uint8_t *frame, int len){

    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        uint16_t len = *(uint16_t *)(pFrame+1);
        int offset = 5+get_frame_sa_sc_addr_len(pFrame[4])+1+2;
        len -= offset;
        len -= 2;
        return len;
    }
    return 0;
}

uint8_t Parse_Packet::get_apdu_type(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        uint16_t len = *(uint16_t *)(pFrame+1);
        int offset = 5+get_frame_sa_sc_addr_len(pFrame[4])+1+2;
        len -= offset;
        len -= 2;
        return *((uint8_t*)(pFrame+offset));
    }
    return 0;
}

uint16_t Parse_Packet::get_frame_fcs(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        int offset = get_frame_l(frame, len)+1-2;
        return *(uint16_t*)(pFrame+offset);
    }
    return 0;
}

uint8_t Parse_Packet::get_frame_em(const uint8_t *frame, int len){
    uint8_t *pFrame = get_real_data(frame, len);
    if(NULL != pFrame){
        int offset = get_frame_l(frame, len)+1;
        return pFrame[offset];
    }
    return 0;
}

uint8_t  *Parse_Packet::get_real_data(const uint8_t *frame, int len){

    if((NULL == frame) || (len < 12)){
        cout << "无效的帧数据" << endl;
        return NULL;
    }

    if(0 == memcmp(frame, c_dlt698_frame.lc, sizeof(c_dlt698_frame.lc))){
        if(0x68 == frame[4]){
            return (uint8_t *)(frame+4);
        }
    } else if(0x68 == frame[0]){
        return (uint8_t *)frame;
    }
    return NULL;
}
//==============================================
//获取控制域格式化内容 开始
TRANSMIT_INITIATE_DIRECTION Parse_Packet::get_frame_c_direction(const uint8_t c){
    return (TRANSMIT_INITIATE_DIRECTION)((c >> 6) & 0x03);
}
uint8_t Parse_Packet::get_frame_c_subframe_flag(const uint8_t c){
    return ((c >> 5) & 0x01);
}
uint8_t Parse_Packet::get_frame_c_mix_code(const uint8_t c){
    return ((c >> 3) & 0x01);
}
uint8_t Parse_Packet::get_frame_c_func_code(const uint8_t c){
    return (c & 0x07);
}
//获取控制域格式化内容 结束
//==============================================
//获取地址域格式化内容
DLT698_FRAME_SA_TYPE Parse_Packet::get_frame_sa_sc_addr_type(const uint8_t sa_sc){
    return (DLT698_FRAME_SA_TYPE)((sa_sc >> 6) & 0x03);
}
uint8_t Parse_Packet::get_frame_sa_sc_logic_addr(const uint8_t sa_sc){
    return ((sa_sc >> 4) & 0x03);
}
uint8_t Parse_Packet::get_frame_sa_sc_addr_len(const uint8_t sa_sc){
    return (sa_sc & 0x07)+1;
}
//
//==============================================
//